/*
 * Copyright (c) 1997, 2002, Oracle and/or its affiliates. All rights reserved.
 * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 */

package com.sun.java.swing.plaf.motif;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.plaf.*;
import javax.swing.plaf.basic.BasicTabbedPaneUI;
import java.io.Serializable;

/**
 * A Motif L&F implementation of TabbedPaneUI.
 * <p>
 * <strong>Warning:</strong>
 * Serialized objects of this class will not be compatible with
 * future Swing releases.  The current serialization support is appropriate
 * for short term storage or RMI between applications running the same
 * version of Swing.  A future release of Swing will provide support for
 * long term persistence.
 *
 * @author Amy Fowler
 * @author Philip Milne
 */
public class MotifTabbedPaneUI extends BasicTabbedPaneUI {

    // Instance variables initialized at installation

    protected Color unselectedTabBackground;
    protected Color unselectedTabForeground;
    protected Color unselectedTabShadow;
    protected Color unselectedTabHighlight;

    // UI creation

    public static ComponentUI createUI(JComponent tabbedPane) {
        return new MotifTabbedPaneUI();
    }

    // UI Installation/De-installation

    protected void installDefaults() {
        super.installDefaults();

        unselectedTabBackground = UIManager.getColor("TabbedPane.unselectedTabBackground");
        unselectedTabForeground = UIManager.getColor("TabbedPane.unselectedTabForeground");
        unselectedTabShadow = UIManager.getColor("TabbedPane.unselectedTabShadow");
        unselectedTabHighlight = UIManager.getColor("TabbedPane.unselectedTabHighlight");
    }

    protected void uninstallDefaults() {
        super.uninstallDefaults();

        unselectedTabBackground = null;
        unselectedTabForeground = null;
        unselectedTabShadow = null;
        unselectedTabHighlight = null;
    }

    // UI Rendering

    protected void paintContentBorderTopEdge(Graphics g, int tabPlacement, int selectedIndex, int x, int y, int w, int h) {
        Rectangle selRect = selectedIndex < 0 ? null : getTabBounds(selectedIndex, calcRect);
        g.setColor(lightHighlight);

        // Draw unbroken line if tabs are not on TOP, OR
        // selected tab is not visible (SCROLL_TAB_LAYOUT)
        //
        if (tabPlacement != TOP || selectedIndex < 0 || (selRect.x < x || selRect.x > x + w)) {
            g.drawLine(x, y, x + w - 2, y);
        } else {
            // Break line to show visual connection to selected tab
            g.drawLine(x, y, selRect.x - 1, y);
            if (selRect.x + selRect.width < x + w - 2) {
                g.drawLine(selRect.x + selRect.width, y, x + w - 2, y);
            }
        }
    }

    protected void paintContentBorderBottomEdge(Graphics g, int tabPlacement, int selectedIndex, int x, int y, int w, int h) {
        Rectangle selRect = selectedIndex < 0 ? null : getTabBounds(selectedIndex, calcRect);
        g.setColor(shadow);

        // Draw unbroken line if tabs are not on BOTTOM, OR
        // selected tab is not visible (SCROLL_TAB_LAYOUT)
        //
        if (tabPlacement != BOTTOM || selectedIndex < 0 || (selRect.x < x || selRect.x > x + w)) {
            g.drawLine(x + 1, y + h - 1, x + w - 1, y + h - 1);
        } else {
            // Break line to show visual connection to selected tab
            g.drawLine(x + 1, y + h - 1, selRect.x - 1, y + h - 1);
            if (selRect.x + selRect.width < x + w - 2) {
                g.drawLine(selRect.x + selRect.width, y + h - 1, x + w - 2, y + h - 1);
            }
        }
    }

    protected void paintContentBorderRightEdge(Graphics g, int tabPlacement, int selectedIndex, int x, int y, int w, int h) {
        Rectangle selRect = selectedIndex < 0 ? null : getTabBounds(selectedIndex, calcRect);
        g.setColor(shadow);
        // Draw unbroken line if tabs are not on RIGHT, OR
        // selected tab is not visible (SCROLL_TAB_LAYOUT)
        //
        if (tabPlacement != RIGHT || selectedIndex < 0 || (selRect.y < y || selRect.y > y + h)) {
            g.drawLine(x + w - 1, y + 1, x + w - 1, y + h - 1);
        } else {
            // Break line to show visual connection to selected tab
            g.drawLine(x + w - 1, y + 1, x + w - 1, selRect.y - 1);
            if (selRect.y + selRect.height < y + h - 2) {
                g.drawLine(x + w - 1, selRect.y + selRect.height, x + w - 1, y + h - 2);
            }
        }
    }

    protected void paintTabBackground(Graphics g, int tabPlacement, int tabIndex, int x, int y, int w, int h, boolean isSelected) {
        g.setColor(isSelected ? tabPane.getBackgroundAt(tabIndex) : unselectedTabBackground);
        switch (tabPlacement) {
            case LEFT:
                g.fillRect(x + 1, y + 1, w - 1, h - 2);
                break;
            case RIGHT:
                g.fillRect(x, y + 1, w - 1, h - 2);
                break;
            case BOTTOM:
                g.fillRect(x + 1, y, w - 2, h - 3);
                g.drawLine(x + 2, y + h - 3, x + w - 3, y + h - 3);
                g.drawLine(x + 3, y + h - 2, x + w - 4, y + h - 2);
                break;
            case TOP:
            default:
                g.fillRect(x + 1, y + 3, w - 2, h - 3);
                g.drawLine(x + 2, y + 2, x + w - 3, y + 2);
                g.drawLine(x + 3, y + 1, x + w - 4, y + 1);
        }

    }

    protected void paintTabBorder(Graphics g, int tabPlacement, int tabIndex, int x, int y, int w, int h, boolean isSelected) {
        g.setColor(isSelected ? lightHighlight : unselectedTabHighlight);

        switch (tabPlacement) {
            case LEFT:
                g.drawLine(x, y + 2, x, y + h - 3);
                g.drawLine(x + 1, y + 1, x + 1, y + 2);
                g.drawLine(x + 2, y, x + 2, y + 1);
                g.drawLine(x + 3, y, x + w - 1, y);
                g.setColor(isSelected ? shadow : unselectedTabShadow);
                g.drawLine(x + 1, y + h - 3, x + 1, y + h - 2);
                g.drawLine(x + 2, y + h - 2, x + 2, y + h - 1);
                g.drawLine(x + 3, y + h - 1, x + w - 1, y + h - 1);
                break;
            case RIGHT:
                g.drawLine(x, y, x + w - 3, y);
                g.setColor(isSelected ? shadow : unselectedTabShadow);
                g.drawLine(x + w - 3, y, x + w - 3, y + 1);
                g.drawLine(x + w - 2, y + 1, x + w - 2, y + 2);
                g.drawLine(x + w - 1, y + 2, x + w - 1, y + h - 3);
                g.drawLine(x + w - 2, y + h - 3, x + w - 2, y + h - 2);
                g.drawLine(x + w - 3, y + h - 2, x + w - 3, y + h - 1);
                g.drawLine(x, y + h - 1, x + w - 3, y + h - 1);
                break;
            case BOTTOM:
                g.drawLine(x, y, x, y + h - 3);
                g.drawLine(x + 1, y + h - 3, x + 1, y + h - 2);
                g.drawLine(x + 2, y + h - 2, x + 2, y + h - 1);
                g.setColor(isSelected ? shadow : unselectedTabShadow);
                g.drawLine(x + 3, y + h - 1, x + w - 4, y + h - 1);
                g.drawLine(x + w - 3, y + h - 2, x + w - 3, y + h - 1);
                g.drawLine(x + w - 2, y + h - 3, x + w - 2, y + h - 2);
                g.drawLine(x + w - 1, y, x + w - 1, y + h - 3);
                break;
            case TOP:
            default:
                g.drawLine(x, y + 2, x, y + h - 1);
                g.drawLine(x + 1, y + 1, x + 1, y + 2);
                g.drawLine(x + 2, y, x + 2, y + 1);
                g.drawLine(x + 3, y, x + w - 4, y);
                g.setColor(isSelected ? shadow : unselectedTabShadow);
                g.drawLine(x + w - 3, y, x + w - 3, y + 1);
                g.drawLine(x + w - 2, y + 1, x + w - 2, y + 2);
                g.drawLine(x + w - 1, y + 2, x + w - 1, y + h - 1);
        }

    }

    protected void paintFocusIndicator(Graphics g, int tabPlacement, Rectangle[] rects, int tabIndex, Rectangle iconRect, Rectangle textRect, boolean isSelected) {
        Rectangle tabRect = rects[tabIndex];
        if (tabPane.hasFocus() && isSelected) {
            int x, y, w, h;
            g.setColor(focus);
            switch (tabPlacement) {
                case LEFT:
                    x = tabRect.x + 3;
                    y = tabRect.y + 3;
                    w = tabRect.width - 6;
                    h = tabRect.height - 7;
                    break;
                case RIGHT:
                    x = tabRect.x + 2;
                    y = tabRect.y + 3;
                    w = tabRect.width - 6;
                    h = tabRect.height - 7;
                    break;
                case BOTTOM:
                    x = tabRect.x + 3;
                    y = tabRect.y + 2;
                    w = tabRect.width - 7;
                    h = tabRect.height - 6;
                    break;
                case TOP:
                default:
                    x = tabRect.x + 3;
                    y = tabRect.y + 3;
                    w = tabRect.width - 7;
                    h = tabRect.height - 6;
            }
            g.drawRect(x, y, w, h);
        }
    }

    protected int getTabRunIndent(int tabPlacement, int run) {
        return run * 3;
    }

    protected int getTabRunOverlay(int tabPlacement) {
        tabRunOverlay = (tabPlacement == LEFT || tabPlacement == RIGHT) ? (int) Math.round((float) maxTabWidth * .10) : (int) Math.round((float) maxTabHeight * .22);

        // Ensure that runover lay is not more than insets
        // 2 pixel offset is set from insets to each run
        switch (tabPlacement) {
            case LEFT:
                if (tabRunOverlay > tabInsets.right - 2)
                    tabRunOverlay = tabInsets.right - 2;
                break;
            case RIGHT:
                if (tabRunOverlay > tabInsets.left - 2)
                    tabRunOverlay = tabInsets.left - 2;
                break;
            case TOP:
                if (tabRunOverlay > tabInsets.bottom - 2)
                    tabRunOverlay = tabInsets.bottom - 2;
                break;
            case BOTTOM:
                if (tabRunOverlay > tabInsets.top - 2)
                    tabRunOverlay = tabInsets.top - 2;
                break;

        }

        return tabRunOverlay;
    }

}
